// 云函数入口文件,引入云函数skd
const cloud = require('wx-server-sdk')

// 云函数初始化，必须放在第一个执行
cloud.init({
  // API 调用都保持和云函数当前所在环境一致
  env: cloud.DYNAMIC_CURRENT_ENV
})

// 引入数据库实例
const db = cloud.database()
const comm = db.command
const MAX_LIMIT = 100

/**
 * 保存用户，_id，必传
 * @param {*} args 
 */
async function save(args) {
  const result = await selectByOpenid(args.openid);
  let users = result.data;
  let res = null;
  if(users && users.length > 0) {
    console.log(users[0])
    res = await db.collection("user").doc(users[0]._id).update({
      data :{
        lastLoginTime: new Date()
      }
    });
    return result;
  }
  args.userType = "普通用户"
  return await db.collection("user").add({
    data: args
  });
}

/**
 * 更改用户信息，_id必传
 * @param {*} args 
 */
async function update(args) {
  let data = {
    userType: args.userType === '管理员'?'普通用户':'管理员'
  }
  return await db.collection("user").doc(args._id).update({
    data: data
  });
}

/**
 * 查询用户信息
 */
async function queryList(args) {
  // 先取出集合记录总数
  const countResult = await db.collection('user').count()
  
  const total = countResult.total
  // 计算需分几次取
  const batchTimes = Math.ceil(total / 100)
  // 承载所有读操作的 promise 的数组
  const tasks = []
  for (let i = 0; i < batchTimes; i++) {
    const promise = db.collection('user').skip(i * MAX_LIMIT).limit(MAX_LIMIT).get()
    tasks.push(promise)
  }
  if(tasks.length === 0) {
    return {
      data: [],
      errMsg: 'ok',
    }
  }
  // 等待所有
  return (await Promise.all(tasks)).reduce((acc, cur) => {
    return {
      data: acc.data.concat(cur.data),
      errMsg: acc.errMsg,
    }
  })
}

/**
 * 根据openid查询用户信息
 * @param {*} openid 
 */
async function selectByOpenid(openid) {
  const res = await db.collection("user").where({
    openid: comm.eq(openid)
  }).get();
  return res;
}

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  const {method, args} = event;
  args.openid = wxContext.OPENID;
  let res = null;
  if(method === "save") {
    res = await save(args);
  }else if(method === "update") {
    res = await update(args);
  }else if(method === "queryList") {
    res = await queryList(args);
  }
  return {
    rstData: res,
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
  }
}